
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author rmzn
 */
import lejos.nxt.LCD;
public class FFill{
    public static final int NORTH = 1;
    public static final int EAST  = 2;
    public static final int SOUTH = 3;
    public static final int WEST  = 4;

    public Cell  cell[][];
    public int  coordX = 0;
    public int  coordY = 0;
    public int  rdir   = NORTH;
    public FFill(){
      /*memory allocation...*/
      cell = new Cell[8][8];
      for(int i= 0; i < 8; i++)
         for(int j= 0; j < 8; j++)
         {
           cell[i][j] = new Cell();
           if(i == 0)
             cell[i][j].setWestWall(true);
           if(j == 0)
             cell[i][j].setSouthWall(true);
           if(i == 7)
             cell[i][j].setEastWall(true);
           if(j == 7)
             cell[i][j].setNorthWall(true);
         }
      setDistance();

    }
    public RobotModel robot;
    public void setRobot(RobotModel m){ this.robot = m;}
    public int findMinDistance(int i, int j)
    {
       int min = Cell.MAX_DIST;
       if(!cell[i][j].isWestWall() && i > 0)
         if(min > cell[i-1][j].getDistance())
             min = cell[i-1][j].getDistance();
       if(!cell[i][j].isEastWall()&& i < 7)
         if(min > cell[i+1][j].getDistance())
             min = cell[i+1][j].getDistance();
       if(!cell[i][j].isSouthWall() && j > 0)
         if(min > cell[i][j-1].getDistance())
             min = cell[i][j-1].getDistance();
       if(!cell[i][j].isNorthWall() && j < 7)
         if(min > cell[i][j+1].getDistance())
             min = cell[i][j+1].getDistance();
       if(min < Cell.MAX_DIST)
         cell[i][j].setDistance(min+1);
       return min;
    }
    public void setDistance()
    {
       if(!forward)
       {
          setDefBackDistance();
          return;
       }
       setDefDistance();
       for(int k = 0; k < 3; k++)
       {
           for(int i = 2; i >= 0; i--)
           {
             for(int j = i; j < 8 - i; j++)
             {
                for(int x = i; x < 8 - i; x++)
                {
                    findMinDistance(i,x);
                    findMinDistance(7-i,x);
                    findMinDistance(x,i);
                    findMinDistance(x,7-i);
                }

              }
           }
       }
    }
    public void setDefDistance()
    {
       cell[3][3].setDistance(0);
       cell[3][4].setDistance(0);
       cell[4][3].setDistance(0);
       cell[4][4].setDistance(0);
       //18*4 = 72 işlem.
       for(int i = 2; i >= 0; i--)
       {
         for(int x = i; x < 8 - i; x++)
         {
            cell[i][x].setDistance(Cell.MAX_DIST);
            cell[7-i][x].setDistance(Cell.MAX_DIST);
            cell[x][i].setDistance(Cell.MAX_DIST);
            cell[x][7-i].setDistance(Cell.MAX_DIST);
         }
       }
    }
    public void rDirNorth()
    {
       int min   = Cell.MAX_DIST;
       int dir   = 5;
       //boolean reDistanceRequired = false;
       if(!robot.isFrontWall() && coordX < 7)
       //if(!cell[coordY][coordX].isSetNorthWall()  && coordX < 7)
       {
          cell[coordY][coordX].setNorthWall(false);
          if(min > cell[coordY][coordX+1].getDistance())
          {
             min = cell[coordY][coordX+1].getDistance();
             dir = NORTH;
          }
       }
       else// if(!cell[coordY][coordX].isSetNorthWall())
       {
          cell[coordY][coordX].setNorthWall(true);
          //reDistanceRequired = true;
          setDistance();
       }
       //----------------------------
       if(!robot.isRightWall()&& coordY < 7)
       {
          //cell[coordY][coordX].setEastWall(false);
          if(min > cell[coordY+1][coordX].getDistance())
          {
             min = cell[coordY+1][coordX].getDistance();
             dir = EAST;
          }
       }
       else// if(!cell[coordY][coordX].isSetEastWall())
       {
          cell[coordY][coordX].setEastWall(true);
          //reDistanceRequired = true;
          setDistance();
       }
       //----------------------------
       if(!robot.isLeftWall() && coordY > 0)
       {
          if(min > cell[coordY-1][coordX].getDistance())
          {
             min = cell[coordY-1][coordX].getDistance();
             dir = WEST;
          }
       }
       else// if(!cell[coordY][coordX].isSetWestWall())
       {
          cell[coordY][coordX].setWestWall(true);
          setDistance();
       }
       //-----------------------------------------
       if(!cell[coordY][coordX].isSouthWall()&& coordX > 0)
       {
          if(min > cell[coordY][coordX-1].getDistance())
          {
             min = cell[coordY][coordX-1].getDistance();
             dir = SOUTH;
          }
       }
       /*else //if(!cell[coordY][coordX].isSetSouthWall())
       {
          cell[coordY][coordX].setSouthWall(true);
          setDistance();
       }*/
       //----------------------------
       if(min < Cell.MAX_DIST)
       {

          switch(dir)
          {
            case NORTH: robot.gotoNorth(); coordX++; rdir = dir; break;
            case EAST:  robot.gotoEast(); coordY++; rdir = dir; break;
            case SOUTH: robot.gotoSouth();coordX--; rdir = dir; break;
            case WEST:  robot.gotoWest(); coordY--; rdir = dir; break;
          }
       }
       /*if( cell[coordY][coordX].getDistance() == 0)
       {
           coordX = 0;
           coordY = 0;
           robot.gotoStart();
       }*/
    }
    public void rDirEast()
    {
       int min   = Cell.MAX_DIST;
       int dir   = 5;
       if(!robot.isFrontWall()&& coordY < 7)
       //if(!cell[coordY][coordX].isSetEastWall()&& coordY < 7)
       {
          //cell[coordY][coordX].setEastWall(false);
          if(min > cell[coordY+1][coordX].getDistance())
          {
             min = cell[coordY+1][coordX].getDistance();
             dir = EAST;
          }
       }
       else// if(!cell[coordY][coordX].isSetEastWall())
       {
          cell[coordY][coordX].setEastWall(true);
          //reDistanceRequired = true;
          setDistance();
       }
       //----------------------------
       if(!robot.isRightWall() && coordX > 0)
       {
          //cell[coordY][coordX].setSouthWall(false);
          if(min > cell[coordY][coordX-1].getDistance())
          {
             min = cell[coordY][coordX-1].getDistance();
             dir = SOUTH;
          }
       }       
       else //if(!cell[coordY][coordX].isSetSouthWall())
       {
          cell[coordY][coordX].setSouthWall(true);
          //reDistanceRequired = true;
          setDistance();
       }
       //----------------------------
       if(!robot.isLeftWall() && coordX < 7)
       {
          cell[coordY][coordX].setNorthWall(false);
          if(min > cell[coordY][coordX+1].getDistance())
          {
             min = cell[coordY][coordX+1].getDistance();
             dir = NORTH;
          }
       }
       else// if(!cell[coordY][coordX].isSetNorthWall())
       {
          cell[coordY][coordX].setNorthWall(true);
          //reDistanceRequired = true;
          setDistance();
       }
       //----------------------------
       //boolean reDistanceRequired = false;
       if(!cell[coordY][coordX].isWestWall() && coordY > 0)
       {
          //cell[coordY][coordX].setWestWall(false);
          if(min > cell[coordY-1][coordX].getDistance())
          {
             min = cell[coordY-1][coordX].getDistance();
             dir = WEST;
          }
       }
       /*else// if(!cell[coordY][coordX].isSetWestWall())
       {
          cell[coordY][coordX].setWestWall(true);
          //reDistanceRequired = true;
          setDistance();
       }*/

       if(min < Cell.MAX_DIST)
       {

          switch(dir)
          {
            case NORTH: robot.gotoNorth(); coordX++; rdir = dir; break;
            case EAST:  robot.gotoEast(); coordY++; rdir = dir; break;
            case SOUTH: robot.gotoSouth();coordX--; rdir = dir; break;
            case WEST:  robot.gotoWest(); coordY--; rdir = dir; break;
          }
       }
       /*if( cell[coordY][coordX].getDistance() == 0)
       {
           coordX = 0;
           coordY = 0;
           robot.gotoStart();
       }*/
    }
    public void rDirSouth()
    {
       int min   = Cell.MAX_DIST;
       int dir   = 5;
       if(!robot.isFrontWall()&& coordX > 0 )
       //if(!cell[coordY][coordX].isSetSouthWall()&& coordX > 0 )
       {
          //cell[coordY][coordX].setSouthWall(false);
          if(min > cell[coordY][coordX-1].getDistance())
          {
             min = cell[coordY][coordX-1].getDistance();
             dir = SOUTH;
          }
       }
       else //if(!cell[coordY][coordX].isSetSouthWall())
       {
          cell[coordY][coordX].setSouthWall(true);
          //reDistanceRequired = true;
          setDistance();
       }
       //boolean reDistanceRequired = false;
       if(!robot.isRightWall()&& coordY > 0)
       {
          //cell[coordY][coordX].setWestWall(false);
          if(min > cell[coordY-1][coordX].getDistance())
          {
             min = cell[coordY-1][coordX].getDistance();
             dir = WEST;
          }
       }
       else// if(!cell[coordY][coordX].isSetWestWall())
       {
          cell[coordY][coordX].setWestWall(true);
          //reDistanceRequired = true;
          setDistance();
       }       //----------------------------
       if(!robot.isLeftWall() && coordY < 7)
       {
          //cell[coordY][coordX].setEastWall(false);
          if(min > cell[coordY+1][coordX].getDistance())
          {
             min = cell[coordY+1][coordX].getDistance();
             dir = EAST;
          }
       }
       else// if(!cell[coordY][coordX].isSetEastWall())
       {
          cell[coordY][coordX].setEastWall(true);
          //reDistanceRequired = true;
          setDistance();
       }
       //----------------------------
       
       //----------------------------
       if(!cell[coordY][coordX].isNorthWall() && coordX < 7)
       {
          cell[coordY][coordX].setNorthWall(false);
          if(min > cell[coordY][coordX+1].getDistance())
          {
             min = cell[coordY][coordX+1].getDistance();
             dir = NORTH;
          }
       }/*
       else// if(!cell[coordY][coordX].isSetNorthWall())
       {
          cell[coordY][coordX].setNorthWall(true);
          //reDistanceRequired = true;
          setDistance();
       }*/
       if(min < Cell.MAX_DIST)
       {

          switch(dir)
          {
            case NORTH: robot.gotoNorth(); coordX++; rdir = dir; break;
            case EAST:  robot.gotoEast(); coordY++; rdir = dir; break;
            case SOUTH: robot.gotoSouth();coordX--; rdir = dir; break;
            case WEST:  robot.gotoWest(); coordY--; rdir = dir; break;
          }
       }
       /*if( cell[coordY][coordX].getDistance() == 0)
       {
           coordX = 0;
           coordY = 0;
           robot.gotoStart();
       }*/

    }
    public void rDirWest()
    {
       int min   = Cell.MAX_DIST;
       int dir   = 5;

       //boolean reDistanceRequired = false;
       if(!robot.isFrontWall() && coordY > 0)
       //if(!cell[coordY][coordX].isSetWestWall()  && coordY > 0)
       {
          //cell[coordY][coordX].setWestWall(false);
          if(min > cell[coordY-1][coordX].getDistance())
          {
             min = cell[coordY-1][coordX].getDistance();
             dir = WEST;
          }
       }
       else// if(!cell[coordY][coordX].isSetWestWall())
       {
          //cell[coordY][coordX].setWestWall(true);
          //reDistanceRequired = true;
          //setDistance();
       }
       //----------------------------
       
       //----------------------------
       if(!robot.isRightWall()&& coordX < 7)
       {
          cell[coordY][coordX].setNorthWall(false);
          if(min > cell[coordY][coordX+1].getDistance())
          {
             min = cell[coordY][coordX+1].getDistance();
             dir = NORTH;
          }
       }
       else// if(!cell[coordY][coordX].isSetNorthWall())
       {
          cell[coordY][coordX].setNorthWall(true);
          //reDistanceRequired = true;
          setDistance();
       }
       if(!cell[coordY][coordX].isEastWall()&& coordY < 7)
       {
          //cell[coordY][coordX].setEastWall(false);
          if(min > cell[coordY+1][coordX].getDistance())
          {
             min = cell[coordY+1][coordX].getDistance();
             dir = EAST;
          }
       }
        /*
       else// if(!cell[coordY][coordX].isSetEastWall())
       {
          cell[coordY][coordX].setEastWall(true);
          //reDistanceRequired = true;
          setDistance();
       }*/
       //----------------------------
       if(!robot.isLeftWall()&& coordX > 0)
       {
          //cell[coordY][coordX].setSouthWall(false);
          if(min > cell[coordY][coordX-1].getDistance())
          {
             min = cell[coordY][coordX-1].getDistance();
             dir = SOUTH;
          }
       }
       else //if(!cell[coordY][coordX].isSetSouthWall())
       {
          cell[coordY][coordX].setSouthWall(true);
          //reDistanceRequired = true;
          setDistance();
       }
       //---------------------
       if(min < Cell.MAX_DIST)
       {

          switch(dir)
          {
            case NORTH: robot.gotoNorth(); coordX++; rdir = dir; break;
            case EAST:  robot.gotoEast(); coordY++; rdir = dir; break;
            case SOUTH: robot.gotoSouth();coordX--; rdir = dir; break;
            case WEST:  robot.gotoWest(); coordY--; rdir = dir; break;
          }
       }
       /*if( cell[coordY][coordX].getDistance() == 0)
       {
           coordX = 0;
           coordY = 0;
           robot.gotoStart();
           rdir   = NORTH;
       }*/
    }
    public void wallControl()
    {
      switch(rdir)
      {
            case NORTH:
               if(robot.isLeftWall())
               {
                  cell[coordY][coordX].setWestWall(true);
                  if(coordY > 0)
                    cell[coordY-1][coordX].setEastWall(true);
               }
               //----------------------------
               if(robot.isRightWall())
               {
                  cell[coordY][coordX].setEastWall(true);
                  if(coordY < 7)
                    cell[coordY+1][coordX].setWestWall(true);
               }
               //----------------------------
               if(robot.isFrontWall())
               {
                  cell[coordY][coordX].setNorthWall(true);
                  if(coordX < 7)
                    cell[coordY][coordX+1].setSouthWall(true);
               }
               break;
            case EAST:
               if(robot.isFrontWall())
               {
                  cell[coordY][coordX].setEastWall(true);
                  if(coordY < 7)
                    cell[coordY+1][coordX].setWestWall(true);
               }
               //----------------------------
               if(robot.isRightWall())
               {
                  cell[coordY][coordX].setSouthWall(true);
                  if(coordX > 0)
                    cell[coordY][coordX - 1].setNorthWall(true);
               }
               //----------------------------
               if(robot.isLeftWall())
               {
                  cell[coordY][coordX].setNorthWall(true);
                  if(coordX < 7)
                    cell[coordY][coordX+1].setSouthWall(true);
               }
                break;

            case SOUTH:
                if(robot.isRightWall())
                {
                  cell[coordY][coordX].setWestWall(true);
                  if(coordY > 0)
                    cell[coordY-1][coordX].setEastWall(true);
                }
               //----------------------------
               if(robot.isLeftWall())
               {
                  cell[coordY][coordX].setEastWall(true);
                  if(coordY < 7)
                    cell[coordY+1][coordX].setWestWall(true);
               }
               //----------------------------
               if(robot.isFrontWall())
               {
                  cell[coordY][coordX].setSouthWall(true);
                  if(coordX > 0)
                    cell[coordY][coordX-1].setNorthWall(true);
               }
               break;
            case WEST:
               if(robot.isFrontWall())
               {
                  cell[coordY][coordX].setWestWall(true);
                  if(coordY > 0)
                    cell[coordY-1][coordX].setEastWall(true);
               }
               //----------------------------
               if(robot.isLeftWall())
               {
                  cell[coordY][coordX].setSouthWall(true);
                  if(coordX > 0)
                    cell[coordY][coordX-1].setNorthWall(true);
               }
               //----------------------------
               if(robot.isRightWall())
               {
                   cell[coordY][coordX].setNorthWall(true);
                   if(coordX < 7)
                    cell[coordY][coordX+1].setSouthWall(true);
               }
                break;
       }
       setDistance();
       
    }
    boolean forward = true;
    public void setDefBackDistance()
    {
       cell[0][0].setDistance(0);
       //18*4 = 72 işlem.
       for(int i = 1; i < 8; i++)
       {
         for(int j = 0; j < 8; j++)
         {
            cell[j][i].setDistance(Cell.MAX_DIST);
            cell[i][j].setDistance(Cell.MAX_DIST);
         }
       }
       setBackDistance();
    }
    public void setBackDistance()
    {
       for(int k = 0; k < 10; k++)
       for(int i = 1; i < 8; i++)
       {
         for(int j = 0; j < 8; j++)
         {
            findMinDistance(j,i);
            findMinDistance(i,j);
         }
       }
    }
    public void nextCell()
    {
      wallControl();
      switch(rdir)
      {
         case NORTH: rDirNorth(); break;
         case EAST:  rDirEast();  break;
         case SOUTH: rDirSouth(); break;
         case WEST:  rDirWest();  break;
      }
      if((coordX == 0 && coordY == 0) && !forward)
      {
          forward = true;
          setDistance();
          //robot.repaint();
          //try{Thread.sleep(10000);}catch(Exception ex){}
      }
      if((coordX == 3 || coordX == 4)&&(coordY == 3 || coordY == 4) && forward)
      {
          forward = false;
          setDefBackDistance();
          //robot.repaint();
          //try{Thread.sleep(2000);}catch(Exception ex){}
      }
      //wallControl();
      //robot.repaint();
      LCD.drawString("Front: " + robot.getFrontSensorValue() + "...", 0, 0);
      LCD.drawString("Left: " + robot.getLeftSensorValue() + "...", 0, 1);
      LCD.drawString("Front: " + robot.getRightSensorValue() + "...", 0, 2);
      
      LCD.drawString("Front: " + robot.isFrontWall() + "...", 0, 3);
      LCD.drawString("Left: " + robot.isLeftWall() + "...", 0, 4);
      LCD.drawString("Right: " + robot.isRightWall() + "...", 0, 5);
      
      LCD.drawString("x: " + coordX + " y: " + coordY + "...", 0, 6);
    }
}
